package jtmcraft.game.units;

import java.awt.Color;
import java.io.Serializable;
import java.util.ArrayList;
import jtmcraft.game.CommandButton;
import jtmcraft.game.Controller;
import jtmcraft.game.units.states.GameUnitState;
import jtmcraft.graphics.Sprite;

/**
 *
 * @author tom
 */
abstract public class GameUnit implements CollisionObserver, Serializable {

    private GameUnitState state;

    private Controller actionHandler;

    protected Sprite sprite;
    private int x;
    private int y;
    private int width;
    private int height;

    private int midX;
    private int midY;

    private int maxDescrution;
    
    private boolean live;
    private Color playerColor;

    /**
     * Game unit durability
     */
    private int durability;
    private int maxDurability = 100;
    private boolean focus = false;
    private boolean invisible = false;
    
    //szybki focus
    private int flashCount = 0;
    private int flashDelay = 10;

    private ArrayList< CommandButton > commandButtons;


    public GameUnit( Controller actionHandler ) {
        CollisionManager.getInstance().registerObserver( this );
        this.actionHandler = actionHandler;
        this.live = true;
    }

    public boolean isLive() {
        return live;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
        calculateMiddle();
    }

    public Sprite getSprite() {
        return sprite;
    }

    public void setSprite(Sprite sprite) {
        this.sprite = sprite;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
        calculateMiddle();
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
        calculateMiddle();
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
        calculateMiddle();
    }

    public int getDurability() {
        return durability;
    }

    public void setDurability(int durability) {
        this.durability = durability;
    }

    public int getMaxDurability() {
        return maxDurability;
    }

    public void setMaxDurability(int maxDurability) {
        this.maxDurability = maxDurability;
    }

    
    
    public void decreseDurability(int hit) {
        durability -= hit;
        if( durability <= 0 ) {
            live  = false;
            state = null;            
            CollisionManager.getInstance().unregisterObserver( this );
            actionHandler.destroyUnit( this );
        }
    }

    public boolean isFocus() {
        return focus;
    }

    public void setFocus(boolean focus) {
        this.focus = focus;
    }

    public void setState(GameUnitState state) {
        this.state = state;
    }

    public void update( long timestamp ) {
        if( null != this.state ) {
            this.state.update( this, timestamp );
        }
    }

    public void select() {
        this.setFocus( true );
    }

    public void deselect() {
        this.setFocus( false );
    }

    public abstract void pointEnemy( GameUnit gameUnit );
    public abstract void pointNeutral( GameUnit gameUnit );
    public abstract void point( int x, int y);

    public boolean hitTest( int x, int y ) {

        return (
            ( x >= this.x && x <= (this.x+this.width) ) &&
            ( y >= this.y && y <= (this.y+this.height) )
        );
    }

    public boolean checkCollision( int x, int y, GameUnit gameUnit ) {
        return hitTest( x, y )
            || hitTest( x+gameUnit.getWidth(), y )
            || hitTest( x, y+gameUnit.getHeight() )
            || hitTest( x+gameUnit.getWidth(), y+gameUnit.getHeight() );
    }



    private void calculateMiddle()
    {
        midX = getX() + (getWidth() / 2)  ;
        midY = getY() + (getHeight() / 2) ;
    }

    public int getMidX() {
        return midX;
    }

    public int getMidY() {
        return midY;
    }

    public Controller getActionHandler() {
        return actionHandler;
    }

    public GameUnitState getState() {
        return state;
    }

    public int getMaxDescrution() {
        return maxDescrution;
    }

    public void setMaxDescrution(int maxDescrution) {
        this.maxDescrution = maxDescrution;
    }

    public void flash()
    {
        flashCount = flashDelay;
    }

    public boolean isFlash()
    {
        return flashCount-- > 0;
    }

    public boolean isInvisible() {
        return invisible;
    }

    public void setInvisible(boolean invisible) {
        this.invisible = invisible;
    }

    public void addCommandButton( CommandButton commandButton )
    {
        if( commandButtons == null )
        {
            commandButtons = new ArrayList< CommandButton >();
        }

        commandButtons.add(commandButton);
    }

    public ArrayList<CommandButton> getCommandButtons() {
        return commandButtons;
    }

    public Color getPlayerColor() {
        return playerColor;
    }

    public void setPlayerColor(Color playerColor) {
        this.playerColor = playerColor;
    }

    
}